home *** CD-ROM | disk | FTP | other *** search
/ Aminet 6 / Aminet 6 - June 1995.iso / Aminet / gfx / 3d / irit50src.lha / irit5 / contrib / mssketch / mssketch.c < prev   
Encoding:
C/C++ Source or Header  |  1995-03-14  |  47.0 KB  |  1,423 lines

  1. /*****************************************************************************
  2. *   An X11 driver using only libx11.a.                         *
  3. *                                         *
  4. * Written by:  Gershon Elber                Ver 0.1, June 1993.  *
  5. *****************************************************************************/
  6.  
  7. #ifdef __hpux
  8. typedef char *caddr_t;           /* Awful kludge. Let me know of a better way. */
  9. #endif /* __hpux */
  10.  
  11. #include <X11/Xlib.h>
  12. #include <X11/Xutil.h>
  13. #include <X11/cursorfont.h>
  14. #include <X11/Xresource.h>
  15.  
  16. #include <Xm/MainW.h>
  17. #include <Xm/PushB.h>
  18. #include <Xm/ToggleB.h>
  19. #include <Xm/RowColumn.h>
  20. #include <Xm/Label.h>
  21. #include <Xm/Scale.h>
  22. #include <Xm/Form.h>            
  23.  
  24. #include <stdio.h>
  25. #include <string.h>
  26. #include <math.h>
  27. #include <ctype.h>
  28.  
  29. #include "irit_sm.h"
  30. #include "genmat.h"
  31. #include "iritprsr.h"
  32. #include "allocate.h"
  33. #include "attribut.h"
  34. #include "ip_cnvrt.h"
  35. #include "cagd_lib.h"
  36. #include "symb_lib.h"
  37. #include "iritgrap.h"
  38. #include "irit_soc.h"
  39.  
  40. #define X11_FONT_NAME        "8x13"
  41.  
  42. #define RESOURCE_NAME        "irit"
  43.  
  44. #define DEFAULT_TRANS_WIDTH    200
  45. #define DEFAULT_TRANS_HEIGHT    500
  46. #define DEFAULT_VIEW_WIDTH    400
  47. #define DEFAULT_VIEW_HEIGHT    400
  48.  
  49. #define X11_MAP_X_COORD(x) (((int) ((x + 1.0) * ViewWidth)) / 2)
  50. #define X11_MAP_Y_COORD(y) (((int) ((1.0 - y) * ViewHeight)) / 2)
  51.  
  52. #define X11_INVMAP_X_COORD(x) (((RealType) 2 * x) / ViewWidth - 1.0)
  53. #define X11_INVMAP_Y_COORD(y) (1.0 - ((RealType) 2 * y) / ViewHeight)
  54.  
  55. /* X global specific staff goes here: */
  56. static Display *XDisplay;
  57. static int XScreen;
  58. static Window XRoot;
  59. static Colormap XColorMap;
  60. static GC XTransGraphContext;
  61. static GC XViewGraphContext;
  62. static Visual *XVisual;
  63. static XImage *XImageBuffer;
  64. static Pixmap XIcon;
  65. static Cursor XCursor;
  66. static XColor BlackColor;
  67. static XFontStruct *XLoadedFont;
  68. static XGCValues CrntColorHighIntensity, CrntColorLowIntensity;
  69. static XColor
  70.     *TransCursorColor = NULL,
  71.     *ViewCursorColor = NULL;
  72. static unsigned long
  73.     TransBackGroundPixel,
  74.     TransBorderPixel,
  75.     TransTextPixel,
  76.     TransSubWinBackPixel,
  77.     TransSubWinBorderPixel,
  78.     ViewBackGroundPixel,
  79.     ViewBorderPixel,
  80.     ViewTextPixel;
  81. static int
  82.     XFontYOffsetToCenter = 0,
  83.     TransHasSize = FALSE,
  84.     TransHasPos = FALSE,
  85.     TransPosX = 0,
  86.     TransPosY = 0,
  87.     ViewHasSize = FALSE,
  88.     ViewHasPos = FALSE,
  89.     ViewPosX = 0,
  90.     ViewPosY = 0,
  91.     CurrentXPosition = 0,
  92.     CurrentYPosition = 0;
  93. static unsigned int
  94.     TransBorderWidth = 1,
  95.     TransSubWinBorderWidth = 1,
  96.     TransWidth = DEFAULT_TRANS_WIDTH,
  97.     TransHeight = DEFAULT_TRANS_HEIGHT,
  98.     ViewBorderWidth = 1,
  99.     ViewWidth = DEFAULT_VIEW_WIDTH,
  100.     ViewHeight = DEFAULT_VIEW_HEIGHT,
  101.     MaxColors = IG_MAX_COLOR;
  102.  
  103. /* X Colors to be used for viewed object (see also iritgrap.h): */
  104. static int XViewColorDefs[IG_MAX_COLOR + 1][3] =
  105. {
  106.     {     0,     0,     0 },  /* 0. IG_IRIT_BLACK */
  107.     {     0,     0, 43350 },  /* 1. IG_IRIT_BLUE */
  108.     {     0, 43350,     0 },  /* 2. IG_IRIT_GREEN */
  109.     {     0, 43350, 43350 },  /* 3. IG_IRIT_CYAN */
  110.     { 43350,     0,     0 },  /* 4. IG_IRIT_RED */
  111.     { 43350,     0, 43350 },  /* 5. IG_IRIT_MAGENTA */
  112.     { 43350, 43350,     0 },  /* 6. IG_IRIT_BROWN */
  113.     { 43350, 43350, 43350 },  /* 7. IG_IRIT_LIGHTGREY */
  114.     { 21675, 21675, 21675 },  /* 8. IG_IRIT_DARKGRAY */
  115.     { 21675, 21675, 65535 },  /* 9. IG_IRIT_LIGHTBLUE */
  116.     { 21675, 65535, 21675 },  /* 10. IG_IRIT_LIGHTGREEN */
  117.     { 21675, 65535, 65535 },  /* 11. IG_IRIT_LIGHTCYAN */
  118.     { 65535, 21675, 21675 },  /* 12. IG_IRIT_LIGHTRED */
  119.     { 65535, 21675, 65535 },  /* 13. IG_IRIT_LIGHTMAGENTA */
  120.     { 65535, 65535, 21675 },  /* 14. IG_IRIT_YELLOW */
  121.     { 65535, 65535, 65535 }   /* 15. IG_IRIT_WHITE */
  122. };
  123. XColor XViewColorsHigh[IG_MAX_COLOR + 1];
  124. XColor XViewColorsLow[IG_MAX_COLOR + 1];
  125.  
  126. /* X Viewing window staff goes here: */
  127. static Window ViewWndw;
  128.  
  129. /* X transformation window staff goes here: */
  130. static Window TransformWndw;
  131. static Window ObjScrTglWndw;
  132. static Window PersOrthoTglWndw, PersOrthoZWndw;
  133. static Window RotateXWndw, RotateYWndw, RotateZWndw;
  134. static Window TranslateXWndw, TranslateYWndw, TranslateZWndw;
  135. static Window ScaleWndw;
  136. static Window DepthCueWndw;
  137. static Window SaveMatrixWndw;
  138. static Window PushMatrixWndw;
  139. static Window PopMatrixWndw;
  140. static Window QuitWndw;
  141.  
  142. /* Motif staff. */
  143. static Widget TopLevel, MainForm;
  144. static RealType OldValue;
  145.  
  146. /* Viewing state variables: */
  147. static int
  148.     SubWindowWidthState2 = 1,
  149.     SubWindowHeightState2 = 1;
  150.  
  151. static void SetColorIndex(int c);
  152. static void SetColorRGB(int Color[3]);
  153. static char *ReadOneXDefault(char *Entry);
  154. static void ReadXDefaults(void);
  155. static void SetTransformWindow(int argc, char **argv);
  156. static void RedrawTransformWindow(void);
  157. static Window SetTransformSubWindow(int SubTransPosX, int SubTransPosY,
  158.             unsigned int SubTransWidth, unsigned int SubTransHeight);
  159. static void RedrawTransformSubWindow(Window Win,
  160.     int SubTransPosX, int SubTransPosY,
  161.     unsigned int SubTransWidth, unsigned int SubTransHeight,
  162.     int DrawMiddleVertLine, char *DrawString);
  163. static void SetViewWindow(int argc, char **argv);
  164. static void GraphicFlush(void);
  165. static IGGraphicEventType GetGraphicEvent(XtAppContext App,
  166.                       RealType *ChangeFactor);
  167. static void DrawText(Window Win, char *Str, int PosX, int PosY,
  168.              unsigned long Color);
  169.  
  170. static void CreateControlPanel(Widget TopLevel);
  171. static void ScalesCB(Widget w, IGGraphicEventType EventType);
  172. static void DragCB(Widget w, IGGraphicEventType EventType);
  173. static void TransformCB(Widget w, int State);
  174.  
  175. /****************************************************************************
  176. * Pop up all windows, read input and display.                    *
  177. ****************************************************************************/
  178. void main(int argc, char **argv)
  179. {
  180.     int i;
  181.     XGCValues values;
  182.     XtAppContext App;
  183.     RealType ChangeFactor;
  184.     IGGraphicEventType Event;
  185.     IPObjectStruct *PObjects;
  186.  
  187.     IGConfigureGlobals("x11drvs", argc, argv);
  188.  
  189.     /* Lets see if we can get access to the X server before we even start: */
  190.     if ((XDisplay = (Display *) XOpenDisplay(NULL)) == NULL) {
  191.     fprintf(stderr, "x11drvs: Failed to access X server, abored.\n");
  192.         exit(-1);
  193.     }
  194.     if ((XLoadedFont = XLoadQueryFont(XDisplay, X11_FONT_NAME)) == NULL) {
  195.     fprintf(stderr,
  196.         "x11drvs: Failed to load required X font \"%s\", aborted.\n",
  197.         X11_FONT_NAME);
  198.     exit(-1);
  199.     }
  200.     XFontYOffsetToCenter = (XLoadedFont -> ascent - XLoadedFont -> descent + 1)
  201.                                     / 2;
  202.  
  203.     XScreen = DefaultScreen(XDisplay);
  204.     XRoot = RootWindow(XDisplay, XScreen);
  205.     XColorMap = DefaultColormap(XDisplay, XScreen);
  206.     XVisual = DefaultVisual(XDisplay, XScreen);
  207.     values.foreground = WhitePixel(XDisplay, XScreen);
  208.     values.background = BlackPixel(XDisplay, XScreen);
  209.     values.font = XLoadedFont -> fid;
  210.     XTransGraphContext = XCreateGC(XDisplay, XRoot,
  211.                   GCForeground | GCBackground | GCFont, &values);
  212.     XViewGraphContext = XCreateGC(XDisplay, XRoot,
  213.                   GCForeground | GCBackground, &values);
  214.     
  215.     if (XDisplay->db == NULL)
  216.     XGetDefault(XDisplay, "", "");
  217.     ReadXDefaults();
  218.  
  219.     for (i = 0; i <= IG_MAX_COLOR; i++) {
  220.     XViewColorsHigh[i].red   = XViewColorDefs[i][0];
  221.     XViewColorsHigh[i].green = XViewColorDefs[i][1];
  222.     XViewColorsHigh[i].blue  = XViewColorDefs[i][2];
  223.  
  224.     /* If fails to allocate the color - take WHITE instead. */
  225.     if (!XAllocColor(XDisplay, XColorMap, &XViewColorsHigh[i]))
  226.         XViewColorsHigh[i].pixel = WhitePixel(XDisplay, XScreen);
  227.  
  228.     XViewColorsLow[i].red   = XViewColorDefs[i][0] / 2;
  229.     XViewColorsLow[i].green = XViewColorDefs[i][1] / 2;
  230.     XViewColorsLow[i].blue  = XViewColorDefs[i][2] / 2;
  231.  
  232.     /* If fails to allocate the color - take WHITE instead. */
  233.     if (!XAllocColor(XDisplay, XColorMap, &XViewColorsLow[i]))
  234.         XViewColorsLow[i].pixel = WhitePixel(XDisplay, XScreen);
  235.     }
  236.  
  237.     IGCreateStateMenu();
  238.  
  239.     TopLevel = XtVaAppInitialize(&App, "Control",
  240.                  NULL, 0, &argc, argv, NULL, NULL);
  241.     if (TransHasSize)
  242.     XtVaSetValues(TopLevel,
  243.               XmNheight, TransHeight,
  244.               NULL);
  245.     if (TransHasPos)
  246.     XtVaSetValues(TopLevel,
  247.               XmNx, TransPosX + TransWidth,
  248.               XmNy, TransPosY,
  249.               NULL);
  250.     CreateControlPanel(TopLevel);
  251.     XtRealizeWidget(TopLevel);
  252.  
  253.     SetTransformWindow(argc, argv);
  254.     SetViewWindow(argc, argv);
  255.  
  256.     while ((Event = GetGraphicEvent(App, &ChangeFactor)) != IG_EVENT_QUIT) {
  257.     if (IGProcessEvent(Event, ChangeFactor * IGGlblChangeFactor))
  258.         IGRedrawViewWindow();
  259.     }
  260.  
  261.     XFreeGC(XDisplay, XViewGraphContext);
  262.     XFreeGC(XDisplay, XTransGraphContext);
  263.     XUnloadFont(XDisplay, XLoadedFont -> fid);
  264.     XCloseDisplay(XDisplay);
  265. }
  266.  
  267. /*****************************************************************************
  268. * Construct global pop up menu.                             *
  269. *****************************************************************************/
  270. void IGCreateStateMenu(void)
  271. {
  272. }
  273.  
  274. /****************************************************************************
  275. * Create Motif Based Control Panel                *
  276. ****************************************************************************/
  277. static void CreateControlPanel(Widget TopLevel)
  278. {
  279.     Widget MainWndw, Slider, QuitButton, Scale, Label1, Label2;
  280.     IGGraphicEventType EventType;
  281.  
  282.     MainWndw = XtVaCreateManagedWidget("Main Window",
  283.                        xmMainWindowWidgetClass,    TopLevel, NULL);
  284.     MainForm = XtVaCreateManagedWidget("Mainform",
  285.                        xmFormWidgetClass,      MainWndw,
  286.                        XmNtopAttachment,       XmATTACH_WIDGET,
  287.                        XmNtopWidget,            MainWndw,
  288.                        XmNbottomAttachment,    XmATTACH_WIDGET,
  289.                        XmNbottomWidget,        MainWndw,  
  290.                        XmNleftAttachment,      XmATTACH_WIDGET,
  291.                        XmNleftWidget,            MainWndw,
  292.                        XmNrightAttachment,     XmATTACH_WIDGET,
  293.                        XmNrightWidget,            MainWndw,
  294.                        XmNfractionBase,        15,
  295.                        NULL);    
  296.  
  297.     Slider = XtVaCreateManagedWidget("Slider",
  298.                      xmFormWidgetClass,    MainForm,
  299.                      XmNtopAttachment,     XmATTACH_FORM,
  300.                      XmNbottomAttachment,  XmATTACH_POSITION,
  301.                      XmNbottomPosition,    14,
  302.                      NULL);
  303.     Label1 = XtVaCreateManagedWidget("Locality",
  304.                      xmLabelWidgetClass, Slider,
  305.                      XmNtopAttachment,   XmATTACH_FORM,
  306.                      NULL);
  307.     Label2 = XtVaCreateManagedWidget("Globality",
  308.                      xmLabelWidgetClass,  Slider,
  309.                      XmNbottomAttachment, XmATTACH_FORM,
  310.                      NULL);
  311.     Scale = XtVaCreateManagedWidget("SliderScale",
  312.                     xmScaleWidgetClass,   Slider,
  313.                     XmNorientation,      XmVERTICAL,
  314.                     XmNtopAttachment,     XmATTACH_WIDGET,
  315.                     XmNtopWidget,         Label1,
  316.                     XmNbottomAttachment,  XmATTACH_WIDGET,
  317.                     XmNbottomWidget,      Label2,
  318.                     XmNminimum,           0,
  319.                     XmNmaximum,          1000,
  320.                     XmNshowValue,      True,
  321.                     XmNdecimalPoints,      2,
  322.                     NULL);    
  323.     XtAddCallback(Scale, XmNvalueChangedCallback,
  324.           (XtCallbackProc) ScalesCB, (XtPointer) EventType);
  325.     XtAddCallback(Scale, XmNdragCallback, (XtCallbackProc) DragCB,
  326.           (XtPointer) EventType);
  327.  
  328.     QuitButton = XtVaCreateManagedWidget("QuitBtn",
  329.                      xmFormWidgetClass,   MainForm,
  330.                      XmNbottomAttachment, XmATTACH_FORM,
  331.                      XmNtopAttachment,    XmATTACH_WIDGET,
  332.                      XmNtopWidget,          Slider,
  333.                      XmNleftAttachment,   XmATTACH_FORM,
  334.                      XmNrightAttachment,  XmATTACH_FORM,
  335.                      NULL);
  336.     QuitButton = XtVaCreateManagedWidget("QUIT",
  337.                      xmPushButtonWidgetClass, QuitButton, 
  338.                      XmNleftAttachment,    XmATTACH_FORM,
  339.                      XmNrightAttachment,   XmATTACH_FORM,
  340.                      XmNbottomAttachment,  XmATTACH_FORM,
  341.                      XmNtopAttachment,     XmATTACH_FORM,
  342.                      NULL);
  343.  
  344.     XtAddCallback(QuitButton, XmNactivateCallback,
  345.           (XtCallbackProc) TransformCB, (XtPointer) IG_EVENT_QUIT);
  346. }
  347.  
  348. /****************************************************************************
  349. * Routine to move in 2D normalized (-1..1) view space.                *
  350. ****************************************************************************/
  351. void IGMoveTo2D(RealType X, RealType Y)
  352. {
  353.     CurrentXPosition = X11_MAP_X_COORD(X);
  354.     CurrentYPosition = X11_MAP_Y_COORD(Y);
  355. }
  356.  
  357. /****************************************************************************
  358. * Routine to draw in 2D normalized (-1..1) view space.                *
  359. ****************************************************************************/
  360. void IGLineTo2D(RealType X, RealType Y)
  361. {
  362.     int NewX, NewY;
  363.  
  364.     XDrawLine(XDisplay, ViewWndw, XViewGraphContext,
  365.           CurrentXPosition,
  366.           CurrentYPosition,
  367.           NewX = X11_MAP_X_COORD(X),
  368.           NewY = X11_MAP_Y_COORD(Y));
  369.  
  370.     CurrentXPosition = NewX;
  371.     CurrentYPosition = NewY;
  372. }
  373.  
  374. /****************************************************************************
  375. * Routine to set the intensity of a color (high or low).            *
  376. ****************************************************************************/
  377. void IGSetColorIntensity(int High)
  378. {
  379.     XChangeGC(XDisplay, XViewGraphContext, GCForeground,
  380.           High ? &CrntColorHighIntensity : &CrntColorLowIntensity);
  381.     IGGlblIntensityHighState = High;
  382. }
  383.  
  384. /****************************************************************************
  385. * Routine to set the color according to the given object's color.        *
  386. ****************************************************************************/
  387. void IGSetColorObj(IPObjectStruct *PObj)
  388. {
  389.     int c, Color[3];
  390.  
  391.     if (AttrGetObjectRGBColor(PObj, &Color[0], &Color[1], &Color[2])) {
  392.     SetColorRGB(Color);
  393.     }
  394.     else if ((c = AttrGetObjectColor(PObj)) != IP_ATTR_NO_COLOR) {
  395.     SetColorIndex(c);
  396.     }
  397.     else {
  398.     /* Use white as default color: */
  399.     SetColorIndex(IG_IRIT_WHITE);
  400.     }
  401. }
  402.  
  403. /****************************************************************************
  404. * Routine to set the line width to draw the given object, in pixels.        *
  405. ****************************************************************************/
  406. void IGSetWidthObj(int Width)
  407. {
  408. }
  409.  
  410. /****************************************************************************
  411. * Routine to set the color according to the given color index.            *
  412. ****************************************************************************/
  413. static void SetColorIndex(int color)
  414. {
  415.     if (color >= MaxColors)
  416.     color = IG_IRIT_WHITE;
  417.  
  418.     CrntColorHighIntensity.foreground = XViewColorsHigh[color].pixel;
  419.     CrntColorLowIntensity.foreground = XViewColorsLow[color].pixel;
  420.     XChangeGC(XDisplay, XViewGraphContext, GCForeground,
  421.           &CrntColorHighIntensity);
  422.     IGGlblIntensityHighState = TRUE;
  423. }
  424.  
  425. /****************************************************************************
  426. * Routine to set the color according to the given RGB values.            *
  427. ****************************************************************************/
  428. static void SetColorRGB(int Color[3])
  429. {
  430.     XColor XClr;
  431.     XGCValues values;
  432.  
  433.     XClr.red   = (Color[0] << 8);
  434.     XClr.green = (Color[1] << 8);
  435.     XClr.blue  = (Color[2] << 8);
  436.  
  437.     /* If fails to allocate the color - take WHITE instead. */
  438.     if (!XAllocColor(XDisplay, XColorMap, &XClr)) {
  439.     fprintf(stderr,
  440.         "x11drvs: Failed to allocate color, selected WHITE instead\n");
  441.     XClr.pixel = WhitePixel(XDisplay, XScreen);
  442.     }
  443.     CrntColorHighIntensity.foreground = XClr.pixel;
  444.  
  445.     XClr.red   = (Color[0] << 7);
  446.     XClr.green = (Color[1] << 7);
  447.     XClr.blue  = (Color[2] << 7);
  448.  
  449.     /* If fails to allocate the color - take WHITE instead. */
  450.     if (!XAllocColor(XDisplay, XColorMap, &XClr)) {
  451.     fprintf(stderr,
  452.         "x11drvs: Failed to allocate color, selected WHITE instead\n");
  453.     XClr.pixel = WhitePixel(XDisplay, XScreen);
  454.     }
  455.     CrntColorLowIntensity.foreground = XClr.pixel;
  456.  
  457.     XChangeGC(XDisplay, XViewGraphContext, GCForeground,
  458.           &CrntColorHighIntensity);
  459.     IGGlblIntensityHighState = TRUE;
  460. }
  461.  
  462. /*****************************************************************************
  463. * Read one default from X resource data base.                     *
  464. *****************************************************************************/
  465. static char *ReadOneXDefault(char *Entry)
  466. {
  467.     XrmString Type;
  468.     XrmValue Result;
  469.     char Line[LINE_LEN_LONG];
  470.  
  471.     sprintf(Line, "%s.%s", RESOURCE_NAME, Entry);
  472.     if ( XrmGetResource(XDisplay->db, Line, "Program.Name", &Type, &Result ) )
  473.     return Result.addr;
  474.     else
  475.     return NULL;
  476. }
  477.  
  478. /*****************************************************************************
  479. * Read Defaults from X data base.                         *
  480. *****************************************************************************/
  481. static void ReadXDefaults(void)
  482. {
  483.     int i;
  484.     XColor Color;
  485.     char *TransBackGroundColor = ReadOneXDefault("Trans.BackGround"),
  486.          *TransBorderColor = ReadOneXDefault("Trans*BorderColor"),
  487.          *TransBorderWidthStr = ReadOneXDefault("Trans*BorderWidth"),
  488.          *TransTextColor = ReadOneXDefault("Trans.TextColor"),
  489.          *TransSubWinBackColor = ReadOneXDefault("Trans.SubWin.BackGround"),
  490.          *TransSubWinBorderColor = ReadOneXDefault("Trans.SubWin.BorderColor"),
  491.          *TransSubWinBorderWidthStr = ReadOneXDefault("Trans.SubWin.BorderWidth"),
  492.          *TransGeometry = ReadOneXDefault("Trans.Geometry"),
  493.          *TransCursorColorStr = ReadOneXDefault("Trans.CursorColor"),
  494.          *ViewBackGroundColor = ReadOneXDefault("View.BackGround"),
  495.          *ViewTextColor = ReadOneXDefault("View.TextColor"),
  496.          *ViewBorderColor = ReadOneXDefault("View.BorderColor"),
  497.          *ViewBorderWidthStr = ReadOneXDefault("View.BorderWidth"),
  498.          *ViewGeometry = ReadOneXDefault("View.Geometry"),
  499.          *ViewCursorColorStr = ReadOneXDefault("View.CursorColor"),
  500.          *MaxColorsStr = ReadOneXDefault("MaxColors");
  501.  
  502.     if (XParseColor(XDisplay, XColorMap, "Black", &BlackColor))
  503.     XAllocColor(XDisplay, XColorMap, &BlackColor);
  504.  
  505.     if (TransBackGroundColor != NULL &&
  506.     XParseColor(XDisplay, XColorMap, TransBackGroundColor, &Color) &&
  507.     XAllocColor(XDisplay, XColorMap, &Color))
  508.     TransBackGroundPixel = Color.pixel;
  509.     else
  510.     TransBackGroundPixel = BlackPixel(XDisplay, XScreen);
  511.  
  512.     if (TransBorderColor != NULL &&
  513.     XParseColor(XDisplay, XColorMap, TransBorderColor, &Color) &&
  514.     XAllocColor(XDisplay, XColorMap, &Color))
  515.     TransBorderPixel = Color.pixel;
  516.     else
  517.     TransBorderPixel = WhitePixel(XDisplay, XScreen);
  518.  
  519.     if (TransBorderWidthStr)
  520.     TransBorderWidth = atoi(TransBorderWidthStr);
  521.     else
  522.     TransBorderWidth = 1;
  523.  
  524.     if (TransTextColor != NULL &&
  525.     XParseColor(XDisplay, XColorMap, TransTextColor, &Color) &&
  526.     XAllocColor(XDisplay, XColorMap, &Color))
  527.     TransTextPixel = Color.pixel;
  528.     else
  529.     TransTextPixel = WhitePixel(XDisplay, XScreen);
  530.  
  531.     if (TransSubWinBackColor != NULL &&
  532.     XParseColor(XDisplay, XColorMap, TransSubWinBackColor, &Color) &&
  533.     XAllocColor(XDisplay, XColorMap, &Color))
  534.     TransSubWinBackPixel = Color.pixel;
  535.     else
  536.     TransSubWinBackPixel = BlackPixel(XDisplay, XScreen);
  537.  
  538.     if (TransSubWinBorderColor != NULL &&
  539.     XParseColor(XDisplay, XColorMap, TransSubWinBorderColor, &Color) &&
  540.     XAllocColor(XDisplay, XColorMap, &Color))
  541.     TransSubWinBorderPixel = Color.pixel;
  542.     else
  543.     TransSubWinBorderPixel = WhitePixel(XDisplay, XScreen);
  544.  
  545.     if (TransSubWinBorderWidthStr)
  546.     TransSubWinBorderWidth = atoi(TransSubWinBorderWidthStr);
  547.     else
  548.     TransSubWinBorderWidth = 1;
  549.  
  550.     if (IGGlblTransPrefPos &&
  551.     sscanf(IGGlblTransPrefPos, "%d,%d,%d,%d",
  552.            &TransPosX, &TransWidth, &TransPosY, &TransHeight) == 4) {
  553.     TransWidth -= TransPosX;
  554.     TransHeight -= TransPosY;
  555.     TransHasSize = TransHasPos = TRUE;
  556.     }
  557.     else if ((IGGlblTransPrefPos == NULL || strlen(IGGlblViewPrefPos) == 0) &&
  558.          TransGeometry) {
  559.     i = XParseGeometry(TransGeometry, &TransPosX, &TransPosY,
  560.                                   &TransWidth, &TransHeight);
  561.     TransHasPos = i & XValue && i & YValue;
  562.     TransHasSize =  i & WidthValue && i & HeightValue;
  563.     }
  564.     else
  565.         TransHasSize = TransHasPos = FALSE;
  566.  
  567.     if (TransCursorColorStr != NULL &&
  568.     XParseColor(XDisplay, XColorMap, TransCursorColorStr, &Color) &&
  569.     XAllocColor(XDisplay, XColorMap, &Color)) {
  570.     TransCursorColor = (XColor *) IritMalloc(sizeof(XColor));
  571.     *TransCursorColor = Color;
  572.     }
  573.     else
  574.     TransCursorColor = NULL;
  575.  
  576.     if (ViewBackGroundColor &&
  577.     XParseColor(XDisplay, XColorMap, ViewBackGroundColor, &Color) &&
  578.     XAllocColor(XDisplay, XColorMap, &Color))
  579.     ViewBackGroundPixel = Color.pixel;
  580.     else
  581.     ViewBackGroundPixel = BlackPixel(XDisplay, XScreen);
  582.  
  583.     if (ViewBorderColor &&
  584.     XParseColor(XDisplay, XColorMap, ViewBorderColor, &Color) &&
  585.     XAllocColor(XDisplay, XColorMap, &Color))
  586.     ViewBorderPixel = Color.pixel;
  587.     else
  588.     ViewBorderPixel = WhitePixel(XDisplay, XScreen);
  589.  
  590.     if (ViewTextColor != NULL &&
  591.     XParseColor(XDisplay, XColorMap, ViewTextColor, &Color) &&
  592.     XAllocColor(XDisplay, XColorMap, &Color))
  593.     ViewTextPixel = Color.pixel;
  594.     else
  595.     ViewTextPixel = WhitePixel(XDisplay, XScreen);
  596.  
  597.     if (ViewBorderWidthStr)
  598.     ViewBorderWidth = atoi(ViewBorderWidthStr);
  599.     else
  600.     ViewBorderWidth = 1;
  601.  
  602.     if (IGGlblViewPrefPos &&
  603.     sscanf(IGGlblViewPrefPos, "%d,%d,%d,%d",
  604.            &ViewPosX, &ViewWidth, &ViewPosY, &ViewHeight) == 4) {
  605.     ViewWidth -= ViewPosX;
  606.     ViewHeight -= ViewPosY;
  607.     ViewHasSize = ViewHasPos = TRUE;
  608.     }
  609.     else if ((IGGlblViewPrefPos == NULL || strlen(IGGlblViewPrefPos) == 0) &&
  610.          ViewGeometry) {
  611.     i = XParseGeometry(ViewGeometry, &ViewPosX, &ViewPosY,
  612.                                  &ViewWidth, &ViewHeight);
  613.     ViewHasPos = i & XValue && i & YValue;
  614.     ViewHasSize = i & WidthValue && i & HeightValue;
  615.     }
  616.     else
  617.     ViewHasSize = ViewHasPos = FALSE;
  618.  
  619.     if (ViewCursorColorStr != NULL &&
  620.     XParseColor(XDisplay, XColorMap, ViewCursorColorStr, &Color) &&
  621.     XAllocColor(XDisplay, XColorMap, &Color)) {
  622.     ViewCursorColor = (XColor *) IritMalloc(sizeof(XColor));
  623.     *ViewCursorColor = Color;
  624.     }
  625.     else
  626.     ViewCursorColor = NULL;
  627.  
  628.     if (MaxColorsStr)
  629.     MaxColors = atoi(MaxColorsStr);
  630.     else
  631.     MaxColors = IG_MAX_COLOR;
  632.  
  633. }
  634.  
  635. /*****************************************************************************
  636. * Set up and draw a transformation window.                     *
  637. *****************************************************************************/
  638. static void SetTransformWindow(int argc, char **argv)
  639. {
  640.     int SubTransPosX, SubTransPosY, SubTransWidth, SubTransHeight;
  641.     long ValueMask;
  642.     XSizeHints Hints;
  643.     XSetWindowAttributes SetWinAttr;
  644.  
  645.     SetWinAttr.background_pixel = TransBackGroundPixel;
  646.     SetWinAttr.border_pixel = TransBorderPixel;
  647.     ValueMask = CWBackPixel | CWBorderPixel;
  648.  
  649.     Hints.flags = PMinSize | PMaxSize;
  650.     Hints.x = Hints.y = 1;
  651.     Hints.min_width = 100;
  652.     Hints.max_width = 1000;
  653.     Hints.min_height = 200;
  654.     Hints.max_height = 1000;
  655.     if (TransHasSize) {
  656.     Hints.flags |= PSize;
  657.     if (TransWidth < Hints.min_width)
  658.         TransWidth = Hints.min_width;
  659.     if (TransWidth > Hints.max_width)
  660.         TransWidth = Hints.max_width;
  661.     if (TransHeight < Hints.min_height)
  662.         TransHeight = Hints.min_height;
  663.     if (TransHeight > Hints.max_height)
  664.         TransHeight = Hints.max_height;
  665.     Hints.width = TransWidth;
  666.     Hints.height = TransHeight;
  667.     }
  668.     else {
  669.     Hints.flags |= PSize;
  670.     Hints.width = TransWidth = DEFAULT_TRANS_WIDTH;
  671.     Hints.height = TransHeight = DEFAULT_TRANS_HEIGHT;
  672.     }
  673.     if (TransHasPos) {
  674.     Hints.flags |= USPosition;
  675.     Hints.x = TransPosX;
  676.     Hints.y = TransPosY;
  677.     }
  678.  
  679.     TransformWndw = XCreateWindow(XDisplay, XRoot,
  680.                   TransPosX, TransPosY,
  681.                   TransWidth, TransHeight,
  682.                       1, 0, CopyFromParent, CopyFromParent,
  683.                       ValueMask, &SetWinAttr);
  684.  
  685.     XSetStandardProperties(XDisplay, TransformWndw,
  686.                RESOURCE_NAME, RESOURCE_NAME, None,
  687.                argv, argc,
  688.                &Hints);
  689.  
  690.     /* Set our own cursor: */
  691.     XCursor = XCreateFontCursor(XDisplay, XC_hand1);
  692.     XDefineCursor(XDisplay, TransformWndw, XCursor);
  693.     if (TransCursorColor != NULL)
  694.     XRecolorCursor(XDisplay, XCursor, TransCursorColor, &BlackColor);
  695.  
  696.     /* Now lets create the sub windows inside. Note we do not place them yet. */
  697.     SubTransPosX = 0;
  698.     SubTransPosY = TransHeight;
  699.     SubTransWidth = TransWidth - SubTransPosX * 2;
  700.     SubTransHeight = TransHeight / 25;
  701.  
  702.     /* OBJECT/SCREEN space toggle: */
  703.     ObjScrTglWndw = SetTransformSubWindow(SubTransPosX, SubTransPosY,
  704.                       SubTransWidth, SubTransHeight);
  705.  
  706.     /* PERSPECTIVE/ORTHOGRPHIC toggle: */
  707.     PersOrthoTglWndw = SetTransformSubWindow(SubTransPosX, SubTransPosY,
  708.                          SubTransWidth, SubTransHeight);
  709.     PersOrthoZWndw = SetTransformSubWindow(SubTransPosX, SubTransPosY,
  710.                          SubTransWidth, SubTransHeight);
  711.  
  712.     /* ROTATE: */
  713.     RotateXWndw = SetTransformSubWindow(SubTransPosX, SubTransPosY,
  714.                     SubTransWidth, SubTransHeight);
  715.     RotateYWndw = SetTransformSubWindow(SubTransPosX, SubTransPosY,
  716.                     SubTransWidth, SubTransHeight);
  717.     RotateZWndw = SetTransformSubWindow(SubTransPosX, SubTransPosY,
  718.                     SubTransWidth, SubTransHeight);
  719.     /* TRANSLATE: */
  720.     TranslateXWndw = SetTransformSubWindow(SubTransPosX, SubTransPosY,
  721.                        SubTransWidth, SubTransHeight);
  722.     TranslateYWndw = SetTransformSubWindow(SubTransPosX, SubTransPosY,
  723.                        SubTransWidth, SubTransHeight);
  724.     TranslateZWndw = SetTransformSubWindow(SubTransPosX, SubTransPosY,
  725.                        SubTransWidth, SubTransHeight);
  726.     /* SCALE: */
  727.     ScaleWndw = SetTransformSubWindow(SubTransPosX, SubTransPosY,
  728.                       SubTransWidth, SubTransHeight);
  729.  
  730.     /* DEPTH CUE: */
  731.     DepthCueWndw = SetTransformSubWindow(SubTransPosX, SubTransPosY,
  732.                      SubTransWidth, SubTransHeight);
  733.  
  734.     /* SAVE MATRIX: */
  735.     SaveMatrixWndw = SetTransformSubWindow(SubTransPosX, SubTransPosY,
  736.                        SubTransWidth, SubTransHeight);
  737.  
  738.     /* PUSH MATRIX: */
  739.     PushMatrixWndw = SetTransformSubWindow(SubTransPosX, SubTransPosY,
  740.                        SubTransWidth, SubTransHeight);
  741.  
  742.     /* POP MATRIX: */
  743.     PopMatrixWndw = SetTransformSubWindow(SubTransPosX, SubTransPosY,
  744.                       SubTransWidth, SubTransHeight);
  745.  
  746.     /* QUIT: */
  747.     QuitWndw = SetTransformSubWindow(SubTransPosX, SubTransPosY,
  748.                      SubTransWidth, SubTransHeight);
  749.  
  750.     XSelectInput(XDisplay, TransformWndw, ExposureMask);
  751. }
  752.  
  753. /*****************************************************************************
  754. * Redraw a transformation window (after exposure or resize events).         *
  755. *****************************************************************************/
  756. static void RedrawTransformWindow(void)
  757. {
  758.     int SubTransPosX, SubTransPosY,
  759.         SizeChanged = FALSE;
  760.     unsigned long SubTransWidth, SubTransHeight;
  761.     long ValueMask;
  762.     XSizeHints Hints;
  763.     XWindowAttributes TransWindowAttr;
  764.     XSetWindowAttributes SetWinAttr;
  765.  
  766.     XClearWindow(XDisplay, TransformWndw);
  767.  
  768.     /* Get the window attributes, and see if it is the same size or not. */
  769.     XGetWindowAttributes(XDisplay, TransformWndw, &TransWindowAttr);
  770.     if (TransWindowAttr.width != TransWidth ||
  771.     TransWindowAttr.height != TransHeight) {
  772.     SizeChanged = TRUE;
  773.     TransWidth = TransWindowAttr.width;
  774.     TransHeight = TransWindowAttr.height;
  775.     }
  776.  
  777.     /* Now lets update the sub windows inside: */
  778.     SubTransPosX = MIN(TransWidth / 10, 20);
  779.     SubTransPosY =  TransHeight / 28;
  780.     SubTransWidth = TransWidth - SubTransPosX * 2;
  781.     SubTransHeight = TransHeight / 28;
  782.  
  783.     /* OBJECT/SCREEN space toggle: */
  784.     RedrawTransformSubWindow(ObjScrTglWndw, SubTransPosX, SubTransPosY,
  785.                  SubTransWidth, SubTransHeight, FALSE,
  786.                  IGGlblTransformMode == IG_TRANS_OBJECT ?
  787.                  "Object" : "Screen");
  788.     SubTransPosY += SubTransHeight * 2;
  789.  
  790.     /* PERSPECTIVE/ORTHOGRAPHIC toggle: */
  791.     RedrawTransformSubWindow(PersOrthoTglWndw, SubTransPosX, SubTransPosY,
  792.                  SubTransWidth, SubTransHeight, FALSE,
  793.                  IGGlblViewMode == IG_VIEW_ORTHOGRAPHIC ?
  794.                  "Orthographic" : "Perspective");
  795.     SubTransPosY += SubTransHeight;
  796.     RedrawTransformSubWindow(PersOrthoZWndw, SubTransPosX, SubTransPosY,
  797.                  SubTransWidth, SubTransHeight, TRUE, NULL);
  798.     SubTransPosY += SubTransHeight;
  799.     DrawText(TransformWndw, "Z", SubTransPosX / 2,
  800.          SubTransPosY - SubTransHeight / 4, TransTextPixel);
  801.     SubTransPosY += SubTransHeight;
  802.  
  803.     /* ROTATE: */
  804.     DrawText(TransformWndw, "Rotate", TransWidth / 2, SubTransPosY,
  805.          TransTextPixel);
  806.     SubTransPosY += SubTransHeight / 2;
  807.     RedrawTransformSubWindow(RotateXWndw, SubTransPosX, SubTransPosY,
  808.                  SubTransWidth, SubTransHeight, TRUE, NULL);
  809.     SubTransPosY += SubTransHeight;
  810.     DrawText(TransformWndw, "X", SubTransPosX / 2,
  811.          SubTransPosY - SubTransHeight / 4, TransTextPixel);
  812.     RedrawTransformSubWindow(RotateYWndw, SubTransPosX, SubTransPosY,
  813.                  SubTransWidth, SubTransHeight, TRUE, NULL);
  814.     SubTransPosY += SubTransHeight;
  815.     DrawText(TransformWndw, "Y", SubTransPosX / 2,
  816.          SubTransPosY - SubTransHeight / 4, TransTextPixel);
  817.     RedrawTransformSubWindow(RotateZWndw, SubTransPosX, SubTransPosY,
  818.                  SubTransWidth, SubTransHeight, TRUE, NULL);
  819.     SubTransPosY += SubTransHeight;
  820.     DrawText(TransformWndw, "Z", SubTransPosX / 2,
  821.          SubTransPosY - SubTransHeight / 4, TransTextPixel);
  822.  
  823.     /* TRANSLATE: */
  824.     SubTransPosY += SubTransHeight;
  825.     DrawText(TransformWndw, "Translate", TransWidth / 2, SubTransPosY,
  826.          TransTextPixel);
  827.     SubTransPosY += SubTransHeight / 2;
  828.     RedrawTransformSubWindow(TranslateXWndw, SubTransPosX, SubTransPosY,
  829.                  SubTransWidth, SubTransHeight, TRUE, NULL);
  830.     SubTransPosY += SubTransHeight;
  831.     DrawText(TransformWndw, "X", SubTransPosX / 2,
  832.          SubTransPosY - SubTransHeight / 4, TransTextPixel);
  833.     RedrawTransformSubWindow(TranslateYWndw, SubTransPosX, SubTransPosY,
  834.                  SubTransWidth, SubTransHeight, TRUE, NULL);
  835.     SubTransPosY += SubTransHeight;
  836.     DrawText(TransformWndw, "Y", SubTransPosX / 2,
  837.          SubTransPosY - SubTransHeight / 4, TransTextPixel);
  838.     RedrawTransformSubWindow(TranslateZWndw, SubTransPosX, SubTransPosY,
  839.                  SubTransWidth, SubTransHeight, TRUE, NULL);
  840.     SubTransPosY += SubTransHeight;
  841.     DrawText(TransformWndw, "Z", SubTransPosX / 2,
  842.          SubTransPosY - SubTransHeight / 4, TransTextPixel);
  843.  
  844.     /* SCALE: */
  845.     SubTransPosY += SubTransHeight;
  846.     DrawText(TransformWndw, "Scale", TransWidth / 2, SubTransPosY,
  847.          TransTextPixel);
  848.     SubTransPosY += SubTransHeight / 2;
  849.     RedrawTransformSubWindow(ScaleWndw, SubTransPosX, SubTransPosY,
  850.                  SubTransWidth, SubTransHeight, TRUE, NULL);
  851.  
  852.     /* DEPTH CUE: */
  853.     SubTransPosY += SubTransHeight * 2;
  854.     RedrawTransformSubWindow(DepthCueWndw, SubTransPosX, SubTransPosY,
  855.                  SubTransWidth, SubTransHeight, FALSE,
  856.                  IGGlblDepthCue ? "Depth Cue" : "No Depth Cue");
  857.  
  858.     /* SAVE MATRIX: */
  859.     SubTransPosY += SubTransHeight * 2;
  860.     RedrawTransformSubWindow(SaveMatrixWndw, SubTransPosX, SubTransPosY,
  861.                  SubTransWidth, SubTransHeight, FALSE,
  862.                  "Save Matrix");
  863.  
  864.     /* PUSH MATRIX: */
  865.     SubTransPosY += SubTransHeight + SubTransHeight / 2;
  866.     RedrawTransformSubWindow(PushMatrixWndw, SubTransPosX, SubTransPosY,
  867.                  SubTransWidth, SubTransHeight, FALSE,
  868.                  "Push Matrix");
  869.  
  870.     /* POP MATRIX: */
  871.     SubTransPosY += SubTransHeight + SubTransHeight / 2;
  872.     RedrawTransformSubWindow(PopMatrixWndw, SubTransPosX, SubTransPosY,
  873.                  SubTransWidth, SubTransHeight, FALSE,
  874.                  "Pop Matrix");
  875.  
  876.     /* QUIT: */
  877.     SubTransPosY += SubTransHeight * 3;
  878.     RedrawTransformSubWindow(QuitWndw, SubTransPosX, SubTransPosY,
  879.                  SubTransWidth, SubTransHeight, FALSE, "Quit" );
  880.  
  881.     /* Save half of the window width so we can refer to the zero point on X */
  882.     /* axes, which is the vertical line in the middle of the window:        */
  883.     SubWindowWidthState2 = SubTransWidth / 2;
  884.     SubWindowHeightState2 = SubTransHeight / 2;
  885.  
  886.     GraphicFlush();
  887. }
  888.  
  889. /*****************************************************************************
  890. * Set up a transformation sub window.                         *
  891. *****************************************************************************/
  892. static Window SetTransformSubWindow(int SubTransPosX, int SubTransPosY,
  893.             unsigned int SubTransWidth, unsigned int SubTransHeight)
  894. {
  895.     long ValueMask;
  896.     XSetWindowAttributes SetWinAttr;
  897.     Window Win;
  898.  
  899.     SetWinAttr.background_pixel = TransSubWinBackPixel;
  900.     SetWinAttr.border_pixel = TransSubWinBorderPixel;
  901.     SetWinAttr.bit_gravity = SetWinAttr.win_gravity = CenterGravity;
  902.     ValueMask = CWBackPixel | CWBorderPixel | CWBitGravity | CWWinGravity;
  903.  
  904.     Win = XCreateWindow(XDisplay, TransformWndw,
  905.             SubTransPosX, SubTransPosY,
  906.             SubTransWidth, SubTransHeight,
  907.             1, 0, CopyFromParent, CopyFromParent,
  908.             ValueMask, &SetWinAttr);
  909.  
  910.     XSelectInput(XDisplay, Win, ButtonPressMask | Button1MotionMask);
  911.  
  912.     XMapWindow(XDisplay, Win);
  913.  
  914.     return Win;
  915. }
  916.  
  917. /*****************************************************************************
  918. * Redraw a transformation sub window.                         *
  919. *****************************************************************************/
  920. static void RedrawTransformSubWindow(Window Win,
  921.     int SubTransPosX, int SubTransPosY,
  922.     unsigned int SubTransWidth, unsigned int SubTransHeight,
  923.     int DrawMiddleVertLine, char *DrawString)
  924. {
  925.     XGCValues values;
  926.  
  927.     XMoveResizeWindow(XDisplay, Win, SubTransPosX, SubTransPosY,
  928.                                        SubTransWidth, SubTransHeight);
  929.     if (DrawMiddleVertLine) {
  930.     values.foreground = TransSubWinBorderPixel;
  931.     XChangeGC(XDisplay, XTransGraphContext, GCForeground, &values);
  932.  
  933.     XDrawLine(XDisplay, Win, XTransGraphContext,
  934.           SubTransWidth / 2, 0, SubTransWidth / 2, SubTransHeight);
  935.     }
  936.     if (DrawString != NULL) {
  937.     DrawText(Win, DrawString, SubTransWidth / 2, SubTransHeight / 2,
  938.          TransTextPixel);
  939.     }
  940. }
  941.  
  942. /*****************************************************************************
  943. * Set up a view window.                                 *
  944. *****************************************************************************/
  945. static void SetViewWindow(int argc, char **argv)
  946. {
  947.     long ValueMask;
  948.     XSizeHints Hints;
  949.     XSetWindowAttributes SetWinAttr;
  950.  
  951.     SetWinAttr.background_pixel = ViewBackGroundPixel;
  952.     SetWinAttr.border_pixel = ViewBorderPixel;
  953.     ValueMask = CWBackPixel | CWBorderPixel;
  954.  
  955.     Hints.flags = PMinSize | PMaxSize;
  956.     Hints.x = Hints.y = 1;
  957.     Hints.min_width = 50;
  958.     Hints.max_width = 1000;
  959.     Hints.min_height = 50;
  960.     Hints.max_height = 1000;
  961.     if (ViewHasSize) {
  962.     Hints.flags |= PSize;
  963.     if (ViewWidth < Hints.min_width)
  964.         ViewWidth = Hints.min_width;
  965.     if (ViewWidth > Hints.max_width)
  966.         ViewWidth = Hints.max_width;
  967.     if (ViewHeight < Hints.min_height)
  968.         ViewHeight = Hints.min_height;
  969.     if (ViewHeight > Hints.max_height)
  970.         ViewHeight = Hints.max_height;
  971.     Hints.width = ViewWidth;
  972.     Hints.height = ViewHeight;
  973.     }
  974.     else {
  975.     Hints.flags |= PSize;
  976.     Hints.width = ViewWidth = DEFAULT_VIEW_WIDTH;
  977.     Hints.height = ViewHeight = DEFAULT_VIEW_HEIGHT;
  978.     }
  979.     if (ViewHasPos) {
  980.     Hints.flags |= USPosition;
  981.     Hints.x = ViewPosX;
  982.     Hints.y = ViewPosY;
  983.     }
  984.  
  985.     ViewWndw = XCreateWindow(XDisplay, XRoot,
  986.                  ViewPosX, ViewPosY,
  987.                  ViewWidth, ViewHeight,
  988.                  1, 0, CopyFromParent, CopyFromParent,
  989.                  ValueMask, &SetWinAttr);
  990.  
  991.     XSetStandardProperties(XDisplay, ViewWndw,
  992.                RESOURCE_NAME, RESOURCE_NAME, None,
  993.                argv, argc,
  994.                &Hints);
  995.  
  996.     /* Set our own cursor: */
  997.     XCursor = XCreateFontCursor(XDisplay, XC_arrow);
  998.     XDefineCursor(XDisplay, ViewWndw, XCursor);
  999.     if (ViewCursorColor != NULL)
  1000.     XRecolorCursor(XDisplay, XCursor, ViewCursorColor, &BlackColor);
  1001.  
  1002.     XSelectInput(XDisplay, ViewWndw,
  1003.          ExposureMask | ButtonPressMask | ButtonReleaseMask | ButtonMotionMask);
  1004.     
  1005.     XMapWindow(XDisplay, ViewWndw);
  1006. }
  1007.  
  1008. /*****************************************************************************
  1009. * Redraw the view window.                             *
  1010. *****************************************************************************/
  1011. void IGRedrawViewWindow(void)
  1012. {
  1013.     IPObjectStruct *PObj;
  1014.  
  1015.     XClearWindow(XDisplay, ViewWndw);
  1016.  
  1017.     switch (IGGlblViewMode) {         /* Update the current view. */
  1018.     case IG_VIEW_ORTHOGRAPHIC:
  1019.         GEN_COPY(IGGlblCrntViewMat, IritPrsrViewMat, sizeof(MatrixType));
  1020.         break;
  1021.     case IG_VIEW_PERSPECTIVE:
  1022.         MatMultTwo4by4(IGGlblCrntViewMat, IritPrsrViewMat,
  1023.                             IritPrsrPrspMat);
  1024.         break;
  1025.     }
  1026.  
  1027.     for (PObj = IGGlblDisplayList; PObj != NULL; PObj = PObj -> Pnext)
  1028.     IGDrawObject(PObj);
  1029. }
  1030.  
  1031. /******************************************************************************
  1032. * Flush output of graphic command.                          *
  1033. ******************************************************************************/
  1034. static void GraphicFlush(void)
  1035. {
  1036.     XFlush(XDisplay);
  1037. }
  1038.  
  1039. /******************************************************************************
  1040. * Handle X events                                  *
  1041. ******************************************************************************/
  1042. static IGGraphicEventType GetGraphicEvent(XtAppContext App,
  1043.                       RealType *ChangeFactor)
  1044. {
  1045.     static int LastX,
  1046.     ButtonPressedViewWndw = FALSE;
  1047.     static CagdPtStruct
  1048.     *PtList = NULL,
  1049.     *PtListTail = NULL;
  1050.     int Dx;
  1051.     XEvent Event;
  1052.     XWindowAttributes WinAttr;
  1053.  
  1054.     XMapWindow(XDisplay, TransformWndw);
  1055.  
  1056.     while (TRUE) {
  1057.     /* Maybe we have something in communication socket. */
  1058.     if (!IGGlblStandAlone &&
  1059.         IGReadObjectsFromSocket(IGGlblViewMode, &IGGlblDisplayList))
  1060.         IGRedrawViewWindow();
  1061.  
  1062.     if (XtAppPending(App)) {
  1063.         XtAppNextEvent(App, &Event);
  1064.  
  1065.         XtDispatchEvent(&Event);
  1066.     }
  1067.  
  1068.     if (XPending(XDisplay)) {
  1069.         XNextEvent(XDisplay, &Event);
  1070.  
  1071.         switch (Event.type) {
  1072.         case Expose:
  1073.                 /* Get rid of all Expose events in the queue. */
  1074.                 while (XCheckWindowEvent(XDisplay, Event.xbutton.window,
  1075.                          ExposureMask, &Event));
  1076.             if (Event.xbutton.window == TransformWndw)
  1077.             RedrawTransformWindow();
  1078.             else if (Event.xbutton.window == ViewWndw) {
  1079.             XGetWindowAttributes(XDisplay, ViewWndw, &WinAttr);
  1080.             ViewWidth = WinAttr.width;
  1081.             ViewHeight = WinAttr.height;
  1082.             IGRedrawViewWindow();
  1083.             }
  1084.             break;
  1085.         case ButtonRelease:
  1086.             if (Event.xbutton.window == ViewWndw) {
  1087.             ButtonPressedViewWndw = FALSE;
  1088. /*
  1089. {
  1090.     static int FCount = 1;
  1091.     int i;
  1092.     char Name[80];
  1093.     CagdPtStruct *Pt;
  1094.     FILE *f;
  1095.  
  1096.     for (i = 0, Pt = PtList; Pt != NULL; Pt = Pt -> Pnext, i++);
  1097.     sprintf(Name, "mouse%d.dat", FCount++);
  1098.     f = fopen(Name, "w");
  1099.     fprintf(f, "[OBJECT MOUSE%dINPUT\n    [POINTLIST %d\n", FCount++, i);
  1100.     for (Pt = PtList; Pt != NULL; Pt = Pt -> Pnext)
  1101.     fprintf(f, "\t[%lf %lf %lf]\n", Pt -> Pt[0], Pt -> Pt[1], Pt -> Pt[2]);
  1102.     fprintf(f, "    ]\n]\n");
  1103.     fclose(f);
  1104. }
  1105. */
  1106.             if (PtList != NULL) {
  1107.                 int Len = CagdListLength(PtList);
  1108.                 CagdCrvStruct
  1109.                 *Crv = BspCrvInterpPts(PtList, 3, MIN(50, Len),
  1110.                                CAGD_CHORD_LEN_PARAM);
  1111.                 IPObjectStruct
  1112.                     *PObj = GenCRVObject(Crv);
  1113.  
  1114.                 CagdPtFreeList(PtList);
  1115.                 PtList = PtListTail = NULL;
  1116.  
  1117. CagdDbg(Crv);
  1118. {
  1119.     static int FCount = 1;
  1120.     int i;
  1121.     char Name[80];
  1122.     CagdPtStruct *Pt;
  1123.     FILE *f;
  1124.  
  1125.     for (i = 0, Pt = PtList; Pt != NULL; Pt = Pt -> Pnext, i++);
  1126.     sprintf(Name, "cmouse%d.dat", FCount++);
  1127.     f = fopen(Name, "w");
  1128.     IritPrsrPutObjectToFile(f, PObj);
  1129.     fclose(f);
  1130. }
  1131.                 PObj -> Pnext = IGGlblDisplayList;
  1132.                 IGGlblDisplayList = PObj;
  1133.             }
  1134.             }
  1135.             break;
  1136.         case ButtonPress:
  1137.             if (Event.xbutton.window == ViewWndw) {
  1138.             ButtonPressedViewWndw = TRUE;
  1139.             break;
  1140.             }
  1141.  
  1142.             LastX = Event.xbutton.x;
  1143.             *ChangeFactor =
  1144.             ((RealType) (LastX - SubWindowWidthState2)) /
  1145.                          SubWindowWidthState2;
  1146.             if (Event.xbutton.window == ObjScrTglWndw) {
  1147.             XClearWindow(XDisplay, ObjScrTglWndw);
  1148.             IGGlblTransformMode =
  1149.                 IGGlblTransformMode == IG_TRANS_OBJECT ?
  1150.                            IG_TRANS_SCREEN :
  1151.                            IG_TRANS_OBJECT;
  1152.             DrawText(ObjScrTglWndw,
  1153.                 IGGlblTransformMode == IG_TRANS_OBJECT ? "Object" :
  1154.                                      "Screen",
  1155.                 SubWindowWidthState2, SubWindowHeightState2,
  1156.                 TransTextPixel);
  1157.             return IG_EVENT_SCR_OBJ_TGL;
  1158.             }
  1159.             else if (Event.xbutton.window == PersOrthoTglWndw) {
  1160.             XClearWindow(XDisplay, PersOrthoTglWndw);
  1161.             IGGlblViewMode =
  1162.                 IGGlblViewMode == IG_VIEW_PERSPECTIVE ?
  1163.                           IG_VIEW_ORTHOGRAPHIC :
  1164.                           IG_VIEW_PERSPECTIVE;
  1165.             DrawText(PersOrthoTglWndw,
  1166.                  IGGlblViewMode == IG_VIEW_PERSPECTIVE ?
  1167.                      "Perspective" : "Orthographic",
  1168.                  SubWindowWidthState2, SubWindowHeightState2,
  1169.                  TransTextPixel);
  1170.             return IG_EVENT_PERS_ORTHO_TGL;
  1171.             }
  1172.             else if (Event.xbutton.window == PersOrthoZWndw) {
  1173.             return IG_EVENT_PERS_ORTHO_Z;
  1174.             }
  1175.             else if (Event.xbutton.window == RotateXWndw) {
  1176.             return IG_EVENT_ROTATE_X;
  1177.             }
  1178.             else if (Event.xbutton.window == RotateYWndw) {
  1179.             return IG_EVENT_ROTATE_Y;
  1180.             }
  1181.             else if (Event.xbutton.window == RotateZWndw) {
  1182.             return IG_EVENT_ROTATE_Z;
  1183.             }
  1184.             else if (Event.xbutton.window == TranslateXWndw) {
  1185.             return IG_EVENT_TRANSLATE_X;
  1186.             }
  1187.             else if (Event.xbutton.window == TranslateYWndw) {
  1188.             return IG_EVENT_TRANSLATE_Y;
  1189.             }
  1190.             else if (Event.xbutton.window == TranslateZWndw) {
  1191.             return IG_EVENT_TRANSLATE_Z;
  1192.             }
  1193.             else if (Event.xbutton.window == ScaleWndw) {
  1194.             return IG_EVENT_SCALE;
  1195.             }
  1196.             else if (Event.xbutton.window == DepthCueWndw) {
  1197.             XClearWindow(XDisplay, DepthCueWndw);
  1198.             IGGlblDepthCue = !IGGlblDepthCue;
  1199.             DrawText(DepthCueWndw,
  1200.                  IGGlblDepthCue ? "Depth Cue" : "No Depth Cue",
  1201.                  SubWindowWidthState2, SubWindowHeightState2,
  1202.                  TransTextPixel);
  1203.             return IG_EVENT_DEPTH_CUE;
  1204.             }
  1205.             else if (Event.xbutton.window == SaveMatrixWndw) {
  1206.             return IG_EVENT_SAVE_MATRIX;
  1207.             }
  1208.             else if (Event.xbutton.window == PushMatrixWndw) {
  1209.             return IG_EVENT_PUSH_MATRIX;
  1210.             }
  1211.             else if (Event.xbutton.window == PopMatrixWndw) {
  1212.             return IG_EVENT_POP_MATRIX;
  1213.             }
  1214.             else if (Event.xbutton.window == QuitWndw) {
  1215.             GraphicFlush();
  1216.             return IG_EVENT_QUIT;
  1217.             }
  1218.             break;
  1219.         case MotionNotify:
  1220.             if (Event.xbutton.window == ViewWndw) {
  1221.             CagdPtStruct
  1222.                 *NewPt = CagdPtNew();
  1223.  
  1224.             XDrawPoint(XDisplay, ViewWndw, XViewGraphContext,
  1225.                    Event.xbutton.x, Event.xbutton.y);
  1226.             GraphicFlush();
  1227.  
  1228.             /* Save the point in a linked list. */
  1229.             NewPt -> Pt[0] = X11_INVMAP_X_COORD(Event.xbutton.x);
  1230.             NewPt -> Pt[1] = X11_INVMAP_Y_COORD(Event.xbutton.y);
  1231.             NewPt -> Pt[2] = 0.0;
  1232.  
  1233.             if (PtList == NULL)
  1234.                 PtList = PtListTail = NewPt;
  1235.             else {
  1236.                 PtListTail -> Pnext = NewPt;
  1237.                 PtListTail = NewPt;
  1238.             }
  1239.             break;
  1240.             }
  1241.  
  1242.             /* We may get events of movement in Y which are ignored. */
  1243.             if (Event.xbutton.x - LastX == 0)
  1244.             break;
  1245.  
  1246.             *ChangeFactor = ((RealType) (Event.xbutton.x - LastX)) /
  1247.                             SubWindowWidthState2;
  1248.             LastX = Event.xbutton.x;
  1249.  
  1250.             if (Event.xbutton.window == PersOrthoZWndw) {
  1251.             return IG_EVENT_PERS_ORTHO_Z;
  1252.             }
  1253.             else if (Event.xbutton.window == RotateXWndw) {
  1254.             return IG_EVENT_ROTATE_X;
  1255.             }
  1256.             else if (Event.xbutton.window == RotateYWndw) {
  1257.             return IG_EVENT_ROTATE_Y;
  1258.             }
  1259.             else if (Event.xbutton.window == RotateZWndw) {
  1260.             return IG_EVENT_ROTATE_Z;
  1261.             }
  1262.             else if (Event.xbutton.window == TranslateXWndw) {
  1263.             return IG_EVENT_TRANSLATE_X;
  1264.             }
  1265.             else if (Event.xbutton.window == TranslateYWndw) {
  1266.             return IG_EVENT_TRANSLATE_Y;
  1267.             }
  1268.             else if (Event.xbutton.window == TranslateZWndw) {
  1269.             return IG_EVENT_TRANSLATE_Z;
  1270.             }
  1271.             else if (Event.xbutton.window == ScaleWndw) {
  1272.             return IG_EVENT_SCALE;
  1273.             }
  1274.             break;
  1275.         default:
  1276.             fprintf(stderr,
  1277.                 "x11drvs: undefined event type %d.\n", Event.type);
  1278.             break;
  1279.         }
  1280.     }
  1281.     IritSleep(10);
  1282.     }
  1283. }
  1284.  
  1285. /******************************************************************************
  1286. * Handle the event of a pop up window.                          *
  1287. ******************************************************************************/
  1288. int IGHandleState(int State, int Refresh)
  1289. {
  1290.     int UpdateView = TRUE;
  1291.     XGCValues values;
  1292.  
  1293.     switch (State) {
  1294.     case IG_STATE_DEPTH_CUE:
  1295.         XClearWindow(XDisplay, DepthCueWndw);
  1296.         IGGlblDepthCue = !IGGlblDepthCue;
  1297.         DrawText(DepthCueWndw,
  1298.              IGGlblDepthCue ? "Depth Cue" : "No Depth Cue",
  1299.              SubWindowWidthState2, SubWindowHeightState2,
  1300.              TransTextPixel);
  1301.  
  1302.         break;
  1303.     case IG_STATE_DOUBLE_BUFFER:
  1304.         IGGlblDoDoubleBuffer = !IGGlblDoDoubleBuffer;
  1305.         break;
  1306.     case IG_STATE_WIDER_LINES:
  1307.         IGGlblLineWidth *= 2;
  1308.         values.line_width = IGGlblLineWidth;
  1309.         XChangeGC(XDisplay, XViewGraphContext, GCLineWidth, &values);
  1310.         break;
  1311.     case IG_STATE_NARROW_LINES:
  1312.         IGGlblLineWidth /= 2;
  1313.         if (IGGlblLineWidth < 1)
  1314.         IGGlblLineWidth = 1;
  1315.         values.line_width = IGGlblLineWidth;
  1316.         XChangeGC(XDisplay, XViewGraphContext, GCLineWidth, &values);
  1317.         break;
  1318.     default:
  1319.         UpdateView = IGDefaultStateHandler(State, Refresh);
  1320.         break;
  1321.     }
  1322.  
  1323.     IGCreateStateMenu();
  1324.  
  1325.     return UpdateView;
  1326. }
  1327.  
  1328. /******************************************************************************
  1329. * Draw text centered at the given position.                      *
  1330. ******************************************************************************/
  1331. static void DrawText(Window Win, char *Str, int PosX, int PosY,
  1332.              unsigned long Color)
  1333. {
  1334.     int Len = strlen(Str),
  1335.         Width = XTextWidth(XLoadedFont, Str, Len);
  1336.     XGCValues values;
  1337.  
  1338.     values.foreground = Color;
  1339.     XChangeGC(XDisplay, XTransGraphContext, GCForeground, &values);
  1340.  
  1341.     XDrawString(XDisplay, Win, XTransGraphContext, PosX - Width / 2,
  1342.         PosY + XFontYOffsetToCenter, Str, Len);
  1343. }
  1344.  
  1345. /*****************************************************************************
  1346. * Routine to make some sound.                             *
  1347. *****************************************************************************/
  1348. void IGIritBeep(void)
  1349. {
  1350.     XBell(XDisplay, 0);
  1351. }
  1352.  
  1353. /*****************************************************************************
  1354. * Scales callbacks of commands of mouse buttons.                 *
  1355. *****************************************************************************/
  1356. static void ScalesCB(Widget w, IGGraphicEventType EventType)
  1357. {
  1358.     int NewValue;
  1359.     char buf[10];
  1360.  
  1361.     XmScaleGetValue(w, &NewValue);
  1362. fprintf(stderr, "ScalesCB = %d\n", NewValue);
  1363.     XmScaleSetValue(w, 0);
  1364.     if (IGProcessEvent(EventType,
  1365.                IGGlblChangeFactor * (NewValue - OldValue) / 100))
  1366.         IGRedrawViewWindow(); 
  1367.     OldValue = 0;
  1368. }
  1369.  
  1370. /*****************************************************************************
  1371. * Scales drag movements.                             *
  1372. *****************************************************************************/
  1373. static void DragCB(Widget w, IGGraphicEventType EventType)
  1374. {
  1375.     int NewValue;
  1376.  
  1377.     XmScaleGetValue(w, &NewValue);
  1378. fprintf(stderr, "DragCB = %d\n", NewValue);
  1379.     if (IGProcessEvent(EventType,
  1380.                IGGlblChangeFactor * (NewValue - OldValue) / 100))
  1381.     IGRedrawViewWindow();
  1382.     OldValue = NewValue;
  1383. }
  1384.  
  1385. /*****************************************************************************
  1386. * Handle transformation window buttons.                         *
  1387. *****************************************************************************/
  1388. static void TransformCB(Widget w, int State)
  1389. {
  1390.     switch(State) {
  1391.     case IG_EVENT_QUIT:
  1392.         exit(0);
  1393.  
  1394.     default:
  1395.         if (IGProcessEvent(State, 1)) 
  1396.             IGRedrawViewWindow();
  1397.     }
  1398. }        
  1399.  
  1400. /*****************************************************************************
  1401. * DESCRIPTION:                                                               M
  1402. *   Should we stop this animation. Senses the event queue of X11.            M
  1403. *                                                                            *
  1404. * PARAMETERS:                                                                M
  1405. *   Anim:     The animation to abort.                                        M
  1406. *                                                                            *
  1407. * RETURN VALUE:                                                              M
  1408. *   int:      TRUE if we need to abort, FALSE otherwise.                     M
  1409. *                                                                            *
  1410. * KEYWORDS:                                                                  M
  1411. *   AnimCheckInterrupt                                                       M
  1412. *****************************************************************************/
  1413. int AnimCheckInterrupt(AnimationStruct *Anim)
  1414. {
  1415.     if (XPending(XDisplay)) {
  1416.     Anim -> StopAnim = TRUE;
  1417.     fprintf(stderr, "\nAnimation was interrupted by the user.\n");
  1418.     return TRUE;
  1419.     }
  1420.     else
  1421.         return FALSE;
  1422. }
  1423.